package com.itheima.day20.demo01_exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

/*
    异常:
        概述:
            程序发生不正常的情况, 就是异常.
        分类:
            异常的顶层类是: Throwable.
                错误Error:
                    不需要我们处理,大多数时候, 你也解决不了.
                    例如: 服务器被炸了, 服务器宕机, 数据库崩溃.
                异常Exception:    这个才是我们所说的异常.
                    编译期异常:  发生在编译期的异常, 我们不处理, 程序编译通不过.
                        非 RuntimeException类及其子类, 都属于 编译期异常.
                    运行时异常:  发生在运行时的异常, 我们不处理, 程序也能通过通过编译.
                        RuntimeException类及其子类, 都属于 运行时异常.
        补充: JVM的默认处理异常的方式.
            JVM的默认处理异常的方式是通过 throws实现的, 会将 异常的类型, 异常的描述信息, 以及异常出现的位置打印到控制台上.
            并终止程序的执行.
        处理方案:
            1. try.catch,finally语句
                格式:
                    try{
                        //可能出问题的代码
                    }catch(异常类型 异常对象) {
                        出问题后的解决方案
                    }finally{
                       这里的代码正常情况下永远会执行, 一般是用来释放资源的.
                    }
                实际开发写法:
                    try{
                        //可能出问题的代码
                    }catch(Exception e) {
                        e.printStackTrace();
                    }finally{
                       这里的代码正常情况下永远会执行, 一般是用来释放资源的.
                    }
                 特点:
                    处理完后, 程序会继续往下执行.
            2. throws 关键字
                表示抛出异常, 自己不处理, 交给: 调用者处理.
                如果main方法中的异常也抛出了, 则当遇到异常时, 程序会终止执行.
        应用场景:
            看异常处理后, 是否需要继续执行程序.
                需要: 用try.
                不需要: 用throws.
        延伸的内容:
            1. 针对于try.catch.finally语句, finally写不写有区别吗?
                有, 因为写在finally里边的内容, 正常情况下, 里边的代码永远会执行, 一般是用来释放资源的.
            2.

 */
public class Demo01 {
    public static void main(String[] args) {
        System.out.println(show());         //30
    }

    public static int show() {
        /*
            try.catch.finally: 正常的执行流程: try, 如果有异常 -> catch -> finally -> catch
         */
        int a = 10;
        try {
            a = 20;
            System.out.println(1 / 0);
            return a;
        } catch (Exception e) {
            a = 30;
            e.printStackTrace();
            return a;       //这行代码做了两件事: 第一件事儿:  创建返回路径, 用来返回变量a的值(30).  第二件事儿: 如果有finally, 则会执行下finally里边的内容.
            //1. 但是在返回a的值之前, 看到还有finally语句, 所以会把finally里边的内容也执行了.
            //2. 执行之后, 在返回catch, 执行return. 虽然在finally里边, 已经修改了变量的值.
            //3. 但是因为第一步return的返回值"路径", 已经标记返回的值就是30, 所以最终我们看到的结果也是: 30
        } finally {
            a = 40;
            System.out.println("finally: " + a);
            System.out.println("看看我执行了吗? ");
        }
    }


    public static void method2() {
        //运行时异常
        //System.out.println(1 / 0);            //ArithmeticException

        //编译期异常
        try {
            FileInputStream fis = new FileInputStream("asdlfjaslf");       //FileNotFoundException
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return;
        } finally {
            //释放资源.
            System.out.println("看看我执行了吗?");
        }
    }
}
